package com.gsbelarus.gedemin.income.fragment;

import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.widget.Toast;

import com.gsbelarus.gedemin.income.App;
import com.gsbelarus.gedemin.income.R;
import com.gsbelarus.gedemin.income.activity.Main;
import com.gsbelarus.gedemin.income.sync.DataBaseHelper;
import com.gsbelarus.gedemin.income.sync.SyncService;
import com.gsbelarus.gedemin.lib.ui.dialog.DialogHelper;
import com.gsbelarus.gedemin.lib.ui.interfaces.OnConfirmDialog;

public class SettingsFragment extends PreferenceFragment {

    public static final String WORK_MODE = "working_mode";
    public static final String LIST_LANG = "list_language";
    public static final String DEVICE_ID = "device_id";
    public static final String SERVER_ADDRESS = "server_address";
    public static final String LOGIN = "login";
    public static final String PASSWORD = "password";

    public static final String SYNC_BUTTON = "button_sync";
    public static final String CLEAR_BUTTON = "button_clear";
    public static final String STATISTIC_BUTTON = "button_statistic";

    public static final String ABOUT_BUTTON = "button_about";

    private boolean initChangeListener;

    private Context context;
    private DialogHelper dialogHelper;

    private ReadStatistic readStatistic = null;
    private boolean isReadStatistic = false;

    private String id;
    private Toast copiedTextToast;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity().getApplicationContext();
        dialogHelper = new DialogHelper(getActivity());

        addPreferencesFromResource(R.xml.pref_auth_lang);

        id = android.provider.Settings.Secure.getString(context.getContentResolver(),
                android.provider.Settings.Secure.ANDROID_ID);
        Preference deviceID = findPreference(DEVICE_ID);
        deviceID.setTitle(R.string.device_id);
        deviceID.setSummary((id == null) ? "null" : id);

        initChangeListener = true;
        bindPreferenceSummaryToValue(findPreference(LIST_LANG));
        bindPreferenceSummaryToValue(findPreference(SERVER_ADDRESS));
        bindPreferenceSummaryToValue(findPreference(LOGIN));
        bindPreferenceSummaryToValue(findPreference(PASSWORD));
        initChangeListener = false;

        findPreference(SYNC_BUTTON).setOnPreferenceClickListener(getClickListner());
        findPreference(CLEAR_BUTTON).setOnPreferenceClickListener(getClickListner());
        findPreference(STATISTIC_BUTTON).setOnPreferenceClickListener(getClickListner());
        findPreference(ABOUT_BUTTON).setOnPreferenceClickListener(getClickListner());
        deviceID.setOnPreferenceClickListener(getClickListner());

        /* Проверяем запущена ли синхронизации, если запущена срабатывает BroadcastReceiver
         и выключает кнопки раздела База Данных */
        Intent intent = new Intent(getActivity(), SyncService.class);
        intent.putExtra(SyncService.STATUS_SYNC, SyncService.NO_SYNC);
        getActivity().startService(intent);
    }

    private Preference.OnPreferenceClickListener getClickListner() {
        return new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                /** обработка нажатия на кнопку ID */
                if (isPrefName(preference, DEVICE_ID)) {
                    ClipboardManager clipboard = (ClipboardManager)
                            context.getSystemService(Context.CLIPBOARD_SERVICE);
                    ClipData clip = ClipData.newPlainText(getString(R.string.device_id), id);
                    if (copiedTextToast != null)
                        copiedTextToast.cancel();
                    copiedTextToast = Toast.makeText(getActivity(), R.string.text_copied, Toast.LENGTH_SHORT);
                    copiedTextToast.show();
                    clipboard.setPrimaryClip(clip);
                }

                if (isPrefName(preference, ABOUT_BUTTON)) {
                    String appVer;
                    try {
                        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
                        appVer = packageInfo.versionName;
                    } catch (PackageManager.NameNotFoundException e) {
                        appVer = null;
                    }

                    String about = getString(R.string.version) + " " + appVer +
                            "\n" + getString(R.string.company);

                    dialogHelper.showDialog(getString(R.string.app_name), about, null);
                }

                /** обработка нажатия на Синхронизировать */
                if (isPrefName(preference, SYNC_BUTTON)) {
                    context.startService(new Intent(getActivity(), SyncService.class));

                    /** обработка нажатия на Очистить */
                } else if (isPrefName(preference, CLEAR_BUTTON)) {
                    dialogHelper.setOnConfirmListner(new OnConfirmDialog() {
                        @Override
                        public void confirmDialog(short answer) {
                            switch (answer) {
                                case DialogHelper.CONFIRM_DIALOG_OK:
                                    Intent intent = new Intent(getActivity(), SyncService.class);
                                    intent.putExtra(SyncService.CLEAR_DATABASE, true);
                                    intent.putExtra(SyncService.STATUS_SYNC, SyncService.NO_SYNC);
                                    context.startService(intent);
                                    break;
                                case DialogHelper.CONFIRM_DIALOG_CANCEL:
                                    break;
                            }
                        }
                    });
                    dialogHelper.showConfirmDialog(getString(R.string.clear), getString(R.string.clear_confirm));

                    /** обработка нажатия на Статистика */
                } else if (isPrefName(preference, STATISTIC_BUTTON)) {
                    if (!isReadStatistic) {
                        readStatistic = new ReadStatistic();
                        readStatistic.execute();
                    }
                }
                return true;
            }
        };
    }

    private Preference.OnPreferenceChangeListener getChangeLisntner() {
        return new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object value) {
                String stringValue = value.toString();

                /** вывод подписи для пункта Язык*/
                if (isPrefName(preference, LIST_LANG))
                    preference.setSummary(getLang(stringValue));

                /** вывод подписей для остальных пунктов */
                else if (!stringValue.isEmpty()) {

                    if (isPrefName(preference, PASSWORD))
                        preference.setSummary("*****");
                    else
                        preference.setSummary(stringValue);

                } else {
                    preference.setSummary(getResources().getString(R.string.not_specified_text));
                }

                /** действия при изменении настроек, кроме настроек языка */
                if (!isPrefName(preference, LIST_LANG)) {

                    /** если изменения вызваны инициализацией, то игнорируем */
                    if (!initChangeListener) {
                        savePref(preference, stringValue);
                        if (isData()) {
                            savePrefWorkMode(true);
                            /** не нужно пересоздавать бд при изменении пользователя, пароля или сервера.
                             * Если вместе с сервером сменилась БД, то это отловит проверка гуида.
                             * Пользователь и пароль вполне могут изменитьсябез влияния на данные*/
                            //recreateDB();
                        } else {
                            if (isWorkMode()) {
                                savePrefWorkMode(false);
                                /** не нужно пересоздавать бд при изменении пользователя, пароля или сервера.
                                 * Если вместе с сервером сменилась БД, то это отловит проверка гуида.
                                 * Пользователь и пароль вполне могут изменитьсябез влияния на данные*/
                                //recreateDB();
                            }
                        }
                    }
                } else
                /** действия при изменении настроек языка */
                    if (!initChangeListener) {
                        if (isPrefName(preference, LIST_LANG)) {
                            /** сохраняем язык, изменяем локаль и говорим активности перезапустится */
                            savePref(preference, stringValue);
                            ((App) getActivity().getApplication()).changeLocale();

                            Intent restartIntent = new Intent(context, Main.class);
                            restartIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            restartIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(restartIntent);
                            System.exit(0);
                        }
                    }
                return true;
            }
        };
    }

    /**
     * посылаем сервису задание на удаление и создание/синхронизацию
     */
    private void recreateDB() {
        Intent intent = new Intent(getActivity(), SyncService.class);
        intent.putExtra(SyncService.CLEAR_DATABASE, true);
        context.startService(intent);
    }

    private void bindPreferenceSummaryToValue(Preference preference) {
        Preference.OnPreferenceChangeListener listener = getChangeLisntner();

        preference.setOnPreferenceChangeListener(listener);

        listener.onPreferenceChange(preference,
                PreferenceManager
                        .getDefaultSharedPreferences(preference.getContext())
                        .getString(preference.getKey(), "")
        );
    }

    private void savePrefWorkMode(boolean value) {
        SharedPreferences prefs;
        SharedPreferences.Editor editor;

        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        editor = prefs.edit();

        editor.putBoolean(WORK_MODE, value);
        editor.commit();
    }

    private void savePref(Preference pref, String value) {
        SharedPreferences prefs;
        SharedPreferences.Editor editor;

        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        editor = prefs.edit();

        editor.putString(pref.getKey(), value);
        editor.commit();
    }

    private boolean isWorkMode() {
        SharedPreferences prefs;
        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        return prefs.getBoolean(WORK_MODE, false);
    }

    private boolean isData() {
        SharedPreferences prefs;
        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        if (!prefs.getString(SERVER_ADDRESS, "").isEmpty())
            if (!prefs.getString(LOGIN, "").isEmpty())
                if (!prefs.getString(PASSWORD, "").isEmpty())
                    return true;
        return false;
    }

    private boolean isPrefName(Preference pref, String name) {
        return pref.getKey().equals(name);
    }

    /**
     * @param entryValues сокращенное название языка ("ru", "by")
     * @return локализованное название языка.
     */
    private String getLang(String entryValues) {
        String[] entryValuesArray = getResources().getStringArray(R.array.language_list_values);
        for (int i = 0; i < entryValuesArray.length; i++)
            if (entryValuesArray[i].equals(entryValues))
                return getResources().getStringArray(R.array.language_list_title)[i];
        return "";
    }

    public void setEnabledDataBaseButton(boolean flag) {
        findPreference(SYNC_BUTTON).setEnabled(flag);
        findPreference(CLEAR_BUTTON).setEnabled(flag);
        findPreference(STATISTIC_BUTTON).setEnabled(flag);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (readStatistic != null)
            readStatistic.cancel(true);
    }

    private class ReadStatistic extends AsyncTask<Void, Void, Void> {

        private ProgressDialog progressDialog;
        private String[] statistic = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = dialogHelper.showProgressDialog(null, context.getString(R.string.statistic_progress_bar), true);
        }

        @Override
        protected Void doInBackground(Void... voids) {
            DataBaseHelper dbHelper = DataBaseHelper.getInstance(context);
            statistic = dbHelper.getStatistic();
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            if (!isCancelled()) {
                if (progressDialog.isShowing()) {
                    progressDialog.cancel();
                    if (statistic != null) {
                        String message = getString(R.string.statistic_count) +
                                "\n" + "  " + getString(R.string.statistic_clients) + " " + statistic[0] +
                                "\n" + "  " + getString(R.string.statistic_postings) + " " + statistic[1] +
                                "\n" + getString(R.string.statistic_ver) + " " + statistic[2];
                        dialogHelper.showDialog(getString(R.string.statistic), message, null);
                    }
                }
            }
        }
    }
}
